﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestionAutoEcoleModel;
using log4net;
using GestionAutoEcole.DAO.Util;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace GestionAutoEcole.DAO.Impl
{
    public class EmployeeDaoImpl : BaseRepository<employee>
    {

        private static readonly ILog log = LogManager.GetLogger(typeof(EmployeeDaoImpl));

        private static volatile EmployeeDaoImpl instance;
        private static object syncRoot = new Object();

        private EmployeeDaoImpl() { }

        public static EmployeeDaoImpl getInstance()
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new EmployeeDaoImpl();
                }
            }

            return instance;
        }
        //création d'un employee
        public override void Create(employee el)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin Create");
                }
                using (var context = new autoecolebase())
                {
                    /* 2- récupérer les fonctions à supprimer(en réalité, il y a une seul fonction)*/
                    var deletedFonctions = el.fonction.ToList<fonction>();
                    /* 3-  récupérer la fonction à ajouter, il faut la récupérer du context, comme ça les données ne seront pas dupliquée  */
                    var fonctionEntity = el.fonction.FirstOrDefault();
                    var addedFonctions = context.fonction.Where(u => u.FONCTION_ID == fonctionEntity.FONCTION_ID).ToList<fonction>();
                    /* 4- supprimer les anciennes fonctions */
                    deletedFonctions.ForEach(c => el.fonction.Remove(c));
                    //5- Add new fonction
                    foreach (fonction c in addedFonctions)
                    {
                        //7- Add fonction in existing employee
                        el.fonction.Add(c);
                    }
                    context.employee.AddObject(el);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                log.Error("Create : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End Create");
                }
            }
        }

        //modification employee
        public override void Update(employee entity)
        {
            try
            {
                using (var ctx = new autoecolebase())
                {

                    /* 1- Get existing employee from database */
                    var existingEmployee = ctx.employee.Where(u => u.EMPLOYEE_ID == entity.EMPLOYEE_ID)
                        .FirstOrDefault();

                    existingEmployee.EMPLOYEE_NOM = entity.EMPLOYEE_NOM;
                    existingEmployee.EMPLOYEE_PRENOM = entity.EMPLOYEE_PRENOM;
                    existingEmployee.EMPLOYEE_NOM_UTILISATEUR = entity.EMPLOYEE_NOM_UTILISATEUR;
                    existingEmployee.EMPLOYEE_MOT_DE_PASSE = entity.EMPLOYEE_MOT_DE_PASSE;
                    existingEmployee.EMPLOYEE_ADRESSE = entity.EMPLOYEE_ADRESSE;
                    existingEmployee.EMPLOYEE_CODEPOSTALE = entity.EMPLOYEE_CODEPOSTALE;
                    existingEmployee.EMPLOYEE_VILLE = entity.EMPLOYEE_VILLE;
                    existingEmployee.EMPLOYEE_PORTABLE = entity.EMPLOYEE_PORTABLE;
                    existingEmployee.EMPLOYEE_FIXE = entity.EMPLOYEE_FIXE;
                    existingEmployee.EMPLOYEE_PHOTO = entity.EMPLOYEE_PHOTO;
                    existingEmployee.EMPLOYEE_EMAIL = entity.EMPLOYEE_EMAIL;
                    existingEmployee.EMPLOYEE_DATE_NAISSANCE = entity.EMPLOYEE_DATE_NAISSANCE;

                    /* 2- récupérer les fonctions à supprimer(en réalité, il y a une seul fonction)*/
                    var deletedFonctions = existingEmployee.fonction.ToList<fonction>();

                    /* 3-  récupérer la fonction à ajouter, il faut la récupérer du context, comme ça les données ne seront pas dupliquée  */
                    var fonctionEntity = entity.fonction.FirstOrDefault();
                    var addedFonctions = ctx.fonction.Where(u => u.FONCTION_ID == fonctionEntity.FONCTION_ID).ToList<fonction>();

                    /* 4- supprimer les anciennes fonctions */
                    deletedFonctions.ForEach(c => existingEmployee.fonction.Remove(c));

                    //5- Add new fonction
                    foreach (fonction c in addedFonctions)
                    {

                        //7- Add fonction in existing employee
                        existingEmployee.fonction.Add(c);
                    }
                    //8- Save changes
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                log.Error("Update : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End Update");
                }
            }
        }

        //Supprimer tous les employee
        public override void DeleteAll()
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin DeleteAll");
                }
                using (var context = new autoecolebase())
                {
                    var employeeList = context.employee;
                    foreach (var el in employeeList)
                    {
                        context.DeleteObject(el);
                    }
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                log.Error("DeleteAll : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End DeleteAll");
                }
            }
        }

        //Supprimer un employee
        public override void Delete(employee el)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin Delete");
                }
                using (var context = new autoecolebase())
                {
                    var pers = context.employee.Where(u => u.EMPLOYEE_ID == el.EMPLOYEE_ID).First();
                    context.DeleteObject(pers);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                log.Error("Delete : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End Delete");
                }
            }
        }

        //Récupérer tous les employees
        public override List<employee> GetList()
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin GetList");
                }
                using (var context = new autoecolebase())
                {
                    return context.employee.Include("fonction").ToList();
                }
            }
            catch (Exception ex)
            {
                log.Error("GetList : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End GetList");
                }
            }
        }

        //Récupérer un employee avec son Id
        public override employee FindById(int id)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin FindById");
                }
                using (var context = new autoecolebase())
                {
                    var grp = context.employee.Where(u => u.EMPLOYEE_ID == id);
                    return grp.First();
                }
            }
            catch (Exception ex)
            {
                log.Error("FindById : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End FindById");
                }
            }
        }

        //Récupérer une liste d'employees avec un critère de recherche
        public override List<employee> FindByCriteria(Object criteria)
        {
            try
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Begin FindByCriteria");
                }
                using (var context = new autoecolebase())
                {

                    StringBuilder queryString =
                        new StringBuilder(@"SELECT VALUE grp FROM autoecolebase.employee as grp");
                    SelectBuilder sb = new SelectBuilder();

                    employee grp = (employee)criteria;
                    if (grp.EMPLOYEE_NOM != null && !grp.EMPLOYEE_NOM.Equals(""))
                    {
                        sb.AndSearchLike("grp.EMPLOYEE_NOM", grp.EMPLOYEE_NOM.ToString());
                    }

                    if (grp.EMPLOYEE_PRENOM != null && !grp.EMPLOYEE_PRENOM.Equals(""))
                    {
                        sb.AndSearchLike("grp.EMPLOYEE_PRENOM", grp.EMPLOYEE_PRENOM.ToString());
                    }

                    if (grp.EMPLOYEE_NOM_UTILISATEUR != null && !grp.EMPLOYEE_NOM_UTILISATEUR.Equals(""))
                    {
                        sb.AndSearch("grp.EMPLOYEE_NOM_UTILISATEUR", grp.EMPLOYEE_NOM_UTILISATEUR.ToString());
                    }

                    if (grp.EMPLOYEE_MOT_DE_PASSE != null && !grp.EMPLOYEE_MOT_DE_PASSE.Equals(""))
                    {
                        sb.AndSearch("grp.EMPLOYEE_MOT_DE_PASSE", grp.EMPLOYEE_MOT_DE_PASSE.ToString());
                    }

                    if (grp.EMPLOYEE_PORTABLE != null && !grp.EMPLOYEE_PORTABLE.Equals(""))
                    {
                        sb.AndSearchLike("grp.EMPLOYEE_PORTABLE", grp.EMPLOYEE_PORTABLE.ToString());
                    }

                    if (grp.EMPLOYEE_FIXE != null && !grp.EMPLOYEE_FIXE.Equals(""))
                    {
                        sb.AndSearchLike("grp.EMPLOYEE_FIXE", grp.EMPLOYEE_FIXE.ToString());
                    }

                    if (grp.EMPLOYEE_EMAIL != null && !grp.EMPLOYEE_EMAIL.Equals(""))
                    {
                        sb.AndSearchLike("grp.EMPLOYEE_EMAIL", grp.EMPLOYEE_EMAIL.ToString());
                    }

                    queryString.Append(sb.getQueryString());
                    ObjectQuery<employee> query = new ObjectQuery<employee>(queryString.ToString(), context).Include("fonction");
                    return query.ToList();
                }
            }
            catch (Exception ex)
            {
                log.Error("FindByCriteria : ", ex);
                throw;
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("End FindByCriteria");
                }
            }
        }
    }
}
